<!-- 监控配置 -->
<template>
  <div class="config-container">
    <div class="table-top">
      <px-form ref="formRef" :model="queryParams" :inline="true" class="custom-form-ui search-form">
        <px-form-item label="监控类型" prop="indicatorType">
          <px-select v-model="queryParams.indicatorType" clearable placeholder="请选择监控类型" @change="handleTypeChange">
            <px-option v-for="item in indicatorTypeList" :key="item.value" :label="item.name" :value="item.value" />
          </px-select>
        </px-form-item>
        <px-form-item label="监控对象" prop="indicator">
          <px-tree-select
            v-if="queryParams.indicatorType === 'loss'"
            v-model="queryParams.indicator"
            :data="lossTreeData"
            :render-after-expand="false"
            clearable
            style="width: 100%"
            @node-click="handleTreeSelectClick"
            @change="handleTreeSelectChange"
          />
          <px-select v-else v-model="queryParams.indicator" clearable filterable placeholder="请选择监控对象">
            <px-option v-for="item in indicatorList" :key="item.id" :label="`(${item.value})${item.name}`" :value="`${item.value}:${item.name}`" />
            <!-- <px-option v-for="item in indicatorList" :key="item.id" :label="item.name" :value="item.value" /> -->
          </px-select>
        </px-form-item>
        <div class="search-form-btn">
          <px-button type="primary" @click="handleQuery">搜索</px-button>
          <px-button @click="resetQuery">重置</px-button>
        </div>
      </px-form>
    </div>
    <div class="table-top-btn-container">
      <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_ADD'" type="primary" @click="handleAdd">新增</px-button>
      <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_UPLOAD'" type="primary" plain @click="handleDownloadTemplate">下载模板</px-button>
      <px-upload action="#" :http-request="handleImport" :show-file-list="false" accept=".xlsx, xls" style="margin: 0 16px">
        <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_UPLOAD'" type="primary" plain>批量导入</px-button>
      </px-upload>
      <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_DELETE'" plain @click="handleBatchDelete">删除</px-button>
    </div>

    <div v-loading="tableLoading" class="table-content">
      <px-table height="calc(100vh - 370px)" :data="tableData" size="small" border class="common-table" @selection-change="tableSelect">
        <px-table-column type="selection" fixed width="55" prop="selection" align="center" />
        <px-table-column type="index" label="序号" fixed width="55" align="center" />
        <px-table-column prop="code" label="指标编码" min-width="120" fixed show-overflow-tooltip />
        <px-table-column prop="name" label="指标名称" min-width="120" fixed show-overflow-tooltip />
        <px-table-column prop="indicatorName" label="监控类型" min-width="120" show-overflow-tooltip />
        <px-table-column prop="unit" label="指标单位" min-width="150" show-overflow-tooltip />
        <px-table-column prop="period" label="监控周期" min-width="150" show-overflow-tooltip>
          <template #default="scope">
            {{ scope.row.period === "D" ? "每日" : "每月" }}
          </template>
        </px-table-column>
        <px-table-column prop="spcThreshold" label="厂务预警值" min-width="120" show-overflow-tooltip>
          <template #default="scope">
            {{
              scope.row.spcThreshold === null ? "" : scope.row.indicatorType.includes("损耗") ? `${scope.row.spcThreshold}%` : scope.row.spcThreshold
            }}
          </template>
        </px-table-column>
        <px-table-column prop="hseThreshold" label="HSE预警值" min-width="120" show-overflow-tooltip>
          <template #default="scope">
            {{
              scope.row.hseThreshold === null ? "" : scope.row.indicatorType.includes("损耗") ? `${scope.row.hseThreshold}%` : scope.row.hseThreshold
            }}
          </template>
        </px-table-column>
        <px-table-column label="操作" width="100" fixed="right" align="center">
          <template #default="scope">
            <px-tooltip content="编辑" placement="top">
              <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_EDIT'" link icon="EditPen" type="primary" @click="handleEdit(scope.row)" />
            </px-tooltip>
            <px-tooltip content="删除" placement="top">
              <px-button v-has="'ALL_ENERGY_MONITOR_CONFIGURATION_DELETE'" link icon="Delete" type="danger" @click="handleDelete(scope.row)" />
            </px-tooltip>
          </template>
        </px-table-column>
      </px-table>
      <pagination
        v-show="total > 0"
        v-model:page="pageNum"
        v-model:limit="pageSize"
        class="table-pagination"
        :total="total"
        @pagination="handleQuery"
      />
    </div>

    <!-- 新增/编辑弹窗 -->
    <px-dialog v-model="editDialogVisible" :title="handleType === 'ADD' ? '新增' : '编辑'" width="460" @close="cancelEdit">
      <px-form ref="editFormRef" :model="editFormParams" :rules="rules" :validate-on-rule-change="false" label-width="120px">
        <px-form-item label="监控类型" prop="indicatorType">
          <px-select v-model="editFormParams.indicatorType" clearable placeholder="请选择" style="width: 300px" @change="handleTypeChange">
            <px-option v-for="item in indicatorTypeList" :key="item.value" :label="item.name" :value="item.value" />
          </px-select>
        </px-form-item>
        <px-form-item label="监控对象" prop="indicator">
          <px-tree-select
            v-if="editFormParams.indicatorType === 'loss'"
            v-model="editFormParams.indicator"
            :data="lossTreeData"
            :render-after-expand="false"
            style="width: 300px"
            clearable
            @node-click="handleTreeSelectClick"
            @change="handleTreeSelectChange"
          />
          <px-select
            v-else
            v-model="editFormParams.indicator"
            clearable
            filterable
            placeholder="请选择"
            style="width: 300px"
            @change="changeIndicator"
          >
            <px-option v-for="item in indicatorList" :key="item.id" :label="`(${item.value})${item.name}`" :value="`${item.value}:${item.name}`" />
            <!-- <px-option v-for="item in indicatorList" :key="item.id" :label="item.name" :value="item.value" /> -->
          </px-select>
        </px-form-item>
        <px-form-item label="单位" prop="unit">
          <px-input v-model="editFormParams.unit" placeholder="这是一个单位" disabled style="width: 300px" />
        </px-form-item>
        <px-form-item label="监控周期" prop="cycle">
          <px-select v-model="editFormParams.cycle" clearable placeholder="请选择" style="width: 300px">
            <px-option v-for="item in cycleList" :key="item.value" :label="item.name" :value="item.value" />
          </px-select>
        </px-form-item>
        <px-form-item :label="editFormParams.indicatorType.includes('损耗') ? '厂务预警值(%)' : '厂务预警值'" prop="spec">
          <px-input-number
            v-model="editFormParams.spec"
            :precision="2"
            :min="0.01"
            :max="10000000"
            style="width: 300px"
            placeholder="请输入"
            clearable
          />
        </px-form-item>
        <px-form-item :label="editFormParams.indicatorType.includes('损耗') ? 'HSE预警值(%)' : 'HSE预警值'" prop="hse">
          <px-input-number
            v-model="editFormParams.hse"
            :precision="2"
            :min="0.01"
            :max="10000000"
            style="width: 300px"
            placeholder="请输入"
            clearable
          />
        </px-form-item>
      </px-form>
      <template #footer>
        <span class="dialog-footer">
          <px-button @click="cancelEdit">取消</px-button>
          <px-button type="primary" @click="saveEdit">确定</px-button>
        </span>
      </template>
    </px-dialog>

    <!-- 导入失败提示弹窗 -->
    <px-dialog v-model="uploadErrorVisible" title="导入失败" width="800">
      <ul class="error-list">
        <li v-for="item in uploadErrorList" :key="item">
          {{ item }}
        </li>
      </ul>
    </px-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, toRefs, onMounted, computed } from "vue";
import {
  getMonitorConfigListAPI,
  saveMonitorConfigAPI,
  deleteMonitorConfigAPI,
  uploadMonitorConfigAPI,
  getSpcIndicatorAPI
} from "@/api/modules/energy";
import { queryDictData } from "@/api/common";
import { PxMessage, PxMessageBox } from "px-ui";

defineOptions({
  name: "ALL_ENERGY_MONITOR_CONFIGURATION"
});

const formRef = ref(null);
const editFormRef = ref(null);
const relateIndicatorId = ref("");

const state = reactive({
  indicatorList: [],
  indicatorTypeList: [],
  lossTreeData: [],
  cycleList: [
    {
      name: "每日",
      value: "D"
    },
    {
      name: "每月",
      value: "M"
    }
  ],
  queryParams: {
    indicator: "",
    indicatorType: ""
  },
  tableLoading: false,
  tableData: [],
  total: 0,
  pageNum: 1,
  pageSize: 20,
  handleType: "ADD",
  editDialogVisible: false,
  rowData: {},
  editFormParams: {
    indicator: "",
    unit: "",
    indicatorType: "",
    cycle: "",
    spec: null,
    hse: ""
  },
  tableSelectedData: [],
  uploadErrorVisible: false,
  uploadErrorList: [],
  currentTreeSelectNodeData: {}
});
const {
  indicatorList,
  indicatorTypeList,
  lossTreeData,
  cycleList,
  queryParams,
  tableLoading,
  tableData,
  total,
  pageNum,
  pageSize,
  handleType,
  editDialogVisible,
  editFormParams,
  uploadErrorVisible,
  uploadErrorList
} = toRefs(state);

const rules = computed(() => ({
  indicator: [{ required: true, message: "监控对象不能为空", trigger: "change" }],
  unit: [{ required: true, message: "单位不能为空", trigger: "change" }],
  indicatorType: [{ required: true, message: "能源类型不能为空", trigger: "change" }],
  cycle: [{ required: true, message: "监控周期不能为空", trigger: "change" }],
  spec: [{ required: true, message: "厂务预警值不能为空", trigger: "blur" }]
  // hse: [{ required: true, message: "HSE预警值不能为空", trigger: "blur" }]
}));

onMounted(() => {
  getIndicatorTypeSelect();
  handleQuery();
});

// 监控类型变化
const handleTypeChange = val => {
  if (val) {
    getIndicatorSelect();
  } else {
    state.indicatorList = [];
  }
  state.queryParams.indicator = "";
  state.editFormParams.indicator = "";
  state.currentTreeSelectNodeData = "";
};

// 树形下拉框选中变化的事件
const handleTreeSelectChange = val => {
  if (val) {
    let obj = state.currentTreeSelectNodeData;
    if (state.editDialogVisible) {
      state.editFormParams.indicator = `${obj.value}:${obj.name}`;
      state.editFormParams.unit = "%";
      relateIndicatorId.value = obj?.id ?? "";
    } else {
      state.queryParams.indicator = `${obj.value}:${obj.name}`;
    }
  }
};

// 树形下拉框点击节点的事件
const handleTreeSelectClick = data => {
  console.log("data", data);
  state.currentTreeSelectNodeData = data;
  // 新增和编辑
  if (state.editDialogVisible) {
    state.editFormParams.indicator = `${data.value}:${data.name}`;
    state.editFormParams.unit = "%";
    relateIndicatorId.value = data?.id ?? "";
  } else {
    state.queryParams.indicator = `${data.value}:${data.name}`;
  }
};

// 表格选中变化
const tableSelect = val => {
  state.tableSelectedData = val;
};

// 获取监控对象下拉框数据
const getIndicatorSelect = async () => {
  try {
    let type = queryParams.value.indicatorType || editFormParams.value.indicatorType;
    const params = {
      monitorType: type
    };
    const res = await getSpcIndicatorAPI(params);
    if (res?.length && ["consume", "load"].includes(type)) {
      res?.forEach(i => {
        // 能耗监控
        if (type === "consume") {
          i.name = i?.energyName || "";
          i.value = i?.measureCode || "";
        }
        // 负荷监控
        if (type === "load") {
          i.name = i?.energyName || "";
          i.value = i?.measureCode || "";
        }
      });
      state.indicatorList = res;
    }
    if (res?.length && ["loss"].includes(type)) {
      let resData = processTreeData(res);
      console.log("resData", resData);
      state.lossTreeData = resData;
    }
  } catch (error) {
    console.log(error);
  }
};

const processTreeData = data => {
  return data?.map(node => {
    const newNode = { ...node };
    newNode.name = node?.lossName;
    newNode.label = node?.lossName;
    newNode.value = node?.lossType;
    // 递归处理子节点并保留其他字段
    if (Array.isArray(newNode.lossTypeNames)) {
      newNode.children = processTreeData(newNode.lossTypeNames);
    }
    return newNode;
  });
};

// 获取监控类型下拉框数据
const getIndicatorTypeSelect = async () => {
  const indicatorTypeList = await queryDictData({ typeCode: "ENERGY_CATEGORY_TYPE" });
  state.indicatorTypeList = [...indicatorTypeList];
};

// 查询
const handleQuery = async () => {
  try {
    state.tableLoading = true;
    const { indicator, indicatorType } = state.queryParams;
    // // 根据类型，找到某一项，然后拿到中文名字，目前后端只支持中文名
    // let obj = state.indicatorTypeList?.find(i => i.value === indicatorType);
    const params = {
      pageNum: state.pageNum,
      pageSize: state.pageSize,
      code: indicator === "" ? "" : indicator.split(":")[0],
      name: indicator === "" ? "" : indicator.split(":")[1],
      indicatorType: indicatorType || ""
    };
    const res = await getMonitorConfigListAPI(params);
    state.total = res.total;
    state.tableData = res.data;
  } catch (err) {
    console.log(err);
  } finally {
    state.tableLoading = false;
  }
};

// 重置
const resetQuery = () => {
  formRef.value.resetFields();
  handleQuery();
};

// 监控对象
const changeIndicator = val => {
  let type = editFormParams.value.indicatorType;
  let data = state.indicatorList?.filter(i => i?.value === val?.split(":")[0])[0];

  relateIndicatorId.value = data?.id ?? "";
  if (type === "consume") {
    state.editFormParams.unit = data?.unit || "";
  } else {
    state.editFormParams.unit = "%";
  }
};

// 新增
const handleAdd = () => {
  state.handleType = "ADD";
  state.editDialogVisible = true;
  state.editFormParams = {
    indicator: "",
    unit: "",
    indicatorType: "",
    cycle: "",
    spec: null,
    hse: null
  };
  relateIndicatorId.value = "";
};

// 编辑
const handleEdit = row => {
  state.handleType = "EDIT";
  state.editDialogVisible = true;
  state.rowData = row;
  state.editFormParams = {
    indicator: `${row.code}:${row.name}`,
    unit: row.unit,
    indicatorType: row.indicatorType,
    cycle: row.period,
    spec: row.spcThreshold,
    hse: row.hseThreshold
  };
  relateIndicatorId.value = row?.relateIndicatorId || "";
  getIndicatorSelect();
};

// 取消编辑
const cancelEdit = () => {
  editFormRef.value.resetFields();
  state.editDialogVisible = false;
};

// 保存编辑
const saveEdit = async () => {
  if (editFormParams.value.indicatorType === "loss") {
    if (state.editFormParams.hse > state.editFormParams.spec) {
      PxMessage.warning("HSE预警值需要小于厂务预警值");
      return;
    }
  }
  editFormRef.value.validate(async validate => {
    if (validate) {
      const { indicator, unit, indicatorType, cycle, spec, hse } = state.editFormParams;
      const params = {
        id: state.handleType === "EDIT" ? state.rowData.id : null,
        code: indicator === "" ? "" : indicator.split(":")[0],
        name: indicator === "" ? "" : indicator.split(":")[1],
        unit,
        indicatorType,
        period: cycle,
        spcThreshold: spec,
        hseThreshold: hse,
        relateIndicatorId: relateIndicatorId.value
      };
      const res = await saveMonitorConfigAPI(params);
      if (res.length > 0) {
        PxMessage.error(res);
      } else {
        cancelEdit();
        handleQuery();
        PxMessage.success(`${state.handleType === "EDIT" ? "修改" : "新增"}成功`);
      }
    }
  });
};

// 下载模板
const handleDownloadTemplate = () => {
  const fileUrl = "/models/能源监控配置模板.xlsx";

  // 创建一个隐藏的a标签
  const link = document.createElement("a");
  link.href = fileUrl;

  // 将a标签添加到DOM并触发点击事件
  document.body.appendChild(link);
  link.click();

  // 移除a标签
  document.body.removeChild(link);
};

// 导入
const handleImport = async options => {
  try {
    const { file } = options;
    const formData = new FormData();
    formData.append("file", file);
    const res = await uploadMonitorConfigAPI(formData);
    if (res.length > 0) {
      state.uploadErrorList = res.split("#");
      state.uploadErrorVisible = true;
    } else {
      PxMessage.success("批量导入成功");
    }
    handleQuery();
  } catch (error) {
    console.log(error);
  }
};

// 批量删除
const handleBatchDelete = () => {
  if (state.tableSelectedData.length === 0) {
    PxMessage.error("请选择要删除的数据");
    return;
  }
  const params = {
    id: state.tableSelectedData.map(item => item.id)
  };
  sureDelete(params);
};

// 删除
const handleDelete = row => {
  const params = {
    id: [row.id]
  };
  sureDelete(params);
};

const sureDelete = async params => {
  PxMessageBox.confirm("是否确认删除？", "温馨提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      const res = await deleteMonitorConfigAPI(params);
      if (res.length > 0) {
        PxMessage.error(res);
      } else {
        PxMessage.success("删除成功");
        handleQuery();
      }
    })
    .catch(() => {});
};
</script>

<style lang="scss" scoped>
@import url("@/views/common/energy/energyData/scss/common.scss");

.config-container {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  height: calc(100vh - 133px);
  padding: 24px;
  background-color: #fff;
  border-radius: 8px;
}
</style>
